package model;

import Simulation.Simulable;
import java.util.Observable;
import java.util.Random;
/**
 * *********************************************************************
 * Module: Environnement.java Author: epulapp Purpose: Defines the Class
 * Environnement
 * *********************************************************************
 */
public class Environnement extends Observable implements Simulable {

    private Case[][] tab;
    private int sizeX;
    private int sizeY;
    
    public Environnement(int x, int y) {
        this.sizeX = x;
        this.sizeY = y;
        tab = new Case[this.sizeX][this.sizeY];

        for (int i = 0; i < this.getSizeX(); i++) {
            for (int j = 0; j < this.getSizeY(); j++) {
                tab[i][j] = new Case(i, j, this);
            }
        }
    }

    public void initialiser(int mode) {
        // Mode normal, génération aléatoire
        if (mode == 0) {
            for (int i = 0; i < this.getSizeX(); i++) {
                for (int j = 0; j < this.getSizeY(); j++) {
                    Random rd = new Random();
                    int n = rd.nextInt(100) + 1;
                    if (n <= 30) {
                        tab[i][j].getCell().setEtatN(true);
                    }
                }
            }
        } //Mode avec model
        else if (mode == -1) {
        } // Mode perso
        else {
            for (int i = 0; i < this.getSizeX(); i++) {
                for (int j = 0; j < this.getSizeY(); j++) {
                    tab[i][j].getCell().setEtatN(false);
                }
            }
        }
    }
    

    public int getSizeX() {
        return sizeX;
    }

    public void setSizeX(int sizeX) {
        this.sizeX = sizeX;
    }

    public int getSizeY() {
        return sizeY;
    }

    public void setSizeY(int sizeY) {
        this.sizeY = sizeY;
    }

    public Case[] getVoisine(Case c) {
        Case[] temp = new Case[9];
        int X = c.getPosX();
        int Y = c.getPosY();
        int position = 0;
        int cpt = 0;
        for (int larg = X - 1; larg <= X + 1; larg++) {
            for (int j = Y - 1; j <= Y + 1; j++) {
                // Si la cellule est vivante, on l'insert
                if (larg != X || j != Y) {
                    cpt++;
                    if (larg < 0 || j < 0 || larg >= this.sizeX || j >= this.sizeY) {
                        // System.out.println("Fail : X:"+larg+"   Y:"+j);
                        temp[position] = null;
                    } else {
                        temp[position] = tab[larg][j];
                    }
                    position++;
                }
            }
        }
        return temp;
    }

    public void calculGen() {

        int cpt = 0;
        for (int i = 0; i < this.getSizeX(); i++) {
            for (int j = 0; j < this.getSizeY(); j++) {
                tab[i][j].calculEtatSuivant();
            }
        }
        for (int i = 0; i < this.getSizeX(); i++) {
            for (int j = 0; j < this.getSizeY(); j++) {
                if (tab[i][j].getCell().getEtatN() != tab[i][j].getCell().getEtatNP1()) {
                    cpt++;
                }
                tab[i][j].maj();
            }
        }
        this.sendNotification();
    }

    public Case[][] getTab() {
        return tab;
    }

    public void setTab(Case[][] newTab) {
        tab = newTab;
    }

    @Override
    public void Calculer() {
        this.calculGen();

    }

    public void sendNotification() {
        this.setChanged();
        this.notifyObservers();
    }
}